## Script (Python) "assessmentexplorer_userreport"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##title=Assessment Explorer (by User)
##parameters=

#####################################################################
# Product:      KnowledgeEngine (Plone Edition)
#
# File:         assessmentexplorer_userreport.py
#
# Copyright:    Copyright (c) 2004, Faulkner Technologies
#
# Author:       Brian Oliver
#
# Description:  A python script to control/handle requests from the
#               assessmentexplorer_userreport_render.pt page
#
#####################################################################

#set the default batch size 
batchSize = 15

#get the request from the context... we will use it to find stuff!
request=context.REQUEST

#get the sercurity, user provider, assessment storage and credit management services
securityService = context.knowledgeengine_securityservice
userProviderService = context.knowledgeengine_userproviderservice
assessmentStorageService = context.knowledgeengine_assessmentstorageservice
creditManagementService = context.knowledgeengine_creditmanagementservice

#get the authenticated knowledge engine user
user = userProviderService.getUser(request["AUTHENTICATED_USER"].getId())

#get the specific user for the report
reportUser = userProviderService.getUser(request['userIdentity'])

#determine the model
if request.form.has_key('modelIdentity'):
    model = assessmentStorageService.getModel(request.form['modelIdentity'])    
else:
    #if no model is specified, use the first model
    model = assessmentStorageService.getModels()[0]

#determine the current batch
if request.form.has_key('batchNr'):
    batchNr = int(request.form['batchNr'])    
else:
    batchNr = 0

#determine the sort mode (name, instantCreated, instantModified, isLocked)
if request.form.has_key('sortBy'):
    sortBy = request.form['sortBy']
else:
    sortBy = 'instantModified'

#do we need to change the sort order?
if request.form.has_key('btnExplore'):
    model = assessmentStorageService.getModel(request.form['newModelIdentity'])    
    sortBy = request.form['newSortBy']
    batchNr = 0

#get the number of assessments for the model and user
nrAssessments = assessmentStorageService.getNrAssessmentsForModelAndUser(model, reportUser)

#determine the number of batches
nrBatches = int(nrAssessments / batchSize)
if nrBatches * batchSize < nrAssessments:
    nrBatches = nrBatches + 1

#process navigation
if request.form.has_key('btnFirst'):
    batchNr = 0

elif request.form.has_key('btnBack'):
    batchNr = batchNr - 1

elif request.form.has_key('btnNext'):
    batchNr = batchNr + 1

elif request.form.has_key('btnLast'):
    batchNr = nrBatches + 1

elif request.form.has_key('btnRefresh'):
    pass  #nothing to do if we are refreshing

elif request.form.has_key('btnExplore'):
    pass  #nothing to do if we are re-exploring

elif request.form.has_key('btnDeleteAssessments') or request.form.has_key('btnLockAssessments') or request.form.has_key('btnUnlockAssessments'):
    #build a list of the selected assessments
    assessmentIds = []
    prefix = "chkAssessment"
    for formKey in request.form.keys():
        if prefix == formKey[0:len(prefix)]:
            assessmentId = formKey[len(prefix):]
            assessmentIds += [assessmentId]
    assessments = [assessmentStorageService.loadAssessment(assessmentId, model) for assessmentId in assessmentIds]

    if request.form.has_key('btnDeleteAssessments'):
        #------------------------------------#
        # DELETE ASSESSMENT(s)

        #get permission
        deleteAnyAssessmentPermission = securityService.getEffectivePermission("DeleteAnyAssessment", model.getIdentity(), user.getIdentity())

        #does the user have permission to delete assessment(s)?
        if deleteAnyAssessmentPermission is not None and deleteAnyAssessmentPermission.granted():

            #do we need to refund credits for assessment deletion?
            refundPermission = securityService.getEffectivePermission("RefundCreditsForAssessmentDeletion", model.getIdentity(), user.getIdentity())

            #delete each of the assessments
            deletionCount = 0
            for assessment in assessments:
                #handle the 'onBeforeDeleteAssessment' event for the model
                if model.isEventEnabled("onBeforeDeleteAssessment"):
                    model.getEnabledEvent("onBeforeDeleteAssessment").execute(assessment, user)

                #delete the actual assessment
                assessmentStorageService.deleteAssessment(assessment)

                #refund the credit?
                if refundPermission is not None and refundPermission.granted():            

                    #get the credit transaction that was used to create the assessment (we will reverse that transaction)
                    creditTxn = assessment.getCreditTransactionIdentity()

                    #if we have one... let's reverse it
                    if creditTxn is not None and len(creditTxn) > 0:
                        creditManagementService.reverseCredits(creditTxn, user.getIdentity(), "Refund for deleted assessment [%s]" % assessment.getName())

    if request.form.has_key('btnLockAssessments') or request.form.has_key('btnUnlockAssessments'):
        #------------------------------------#
        # UN/LOCK ASSESSMENT(s)

        #get permission
        changeAnyAssessmentLockStatePermission = securityService.getEffectivePermission('ChangeAnyAssessmentLockState', model.getIdentity(), user.getIdentity());

        #does the user have permission to lock/unlock assessment(s)?
        if changeAnyAssessmentLockStatePermission is not None and changeAnyAssessmentLockStatePermission.granted():

            #locking or unlocking?
            locking = request.form.has_key('btnLockAssessments')

            #lock/unlock the selected assessments
            for assessment in assessments:                 
                #lock it?
                if locking and not assessment.getIsLocked():
                    #handle the 'onBeforeLockAssessmentInAnyRepository' event for the model
                    if model.isEventEnabled("onBeforeLockAssessmentInAnyRepository"):
                        model.getEnabledEvent("onBeforeLockAssessmentInAnyRepository").execute(assessment, user)

                    #lock
                    assessment.setIsLocked(locking)                               

                if not locking and assessment.getIsLocked():                    
                    #unlock
                    assessment.setIsLocked(locking)

                #save the assessment
                assessmentStorageService.saveAssessment(assessment)

elif request["REQUEST_METHOD"] == "POST":
    #direct page navigation
    batchNr = int(request.form['page']) - 1

#ensure we are still in the boundaries of the available batches
if batchNr < 0:
    batchNr = 0
elif batchNr > nrBatches:
    batchNr = nrBatches - 1

#get the assessments
assessments = assessmentStorageService.getAssessmentsForModelAndUser(model, reportUser, batchNr, batchSize, sortBy)

#set the report information in the request
request.set('model', model)
request.set('reportUser', reportUser)
request.set('sortBy', sortBy)
request.set('batchNr', batchNr)
request.set('nrBatches', nrBatches)
request.set('assessments', assessments)
request.set('nrAssessments', nrAssessments)

#forward to the assessmentexplorer_userreport_render.pt page
return context.assessmentexplorer_userreport_render(context, request)
